import ee.ui.application.Application
import ee.ui.javafx.application.JavaFxApplicationLauncher
import ee.ui.primitives.Color
import ee.ui.primitives.VerticalPosition
import ee.ui.javafx.application.Toolkit
import ee.ui.layout.HorizontalLayout
import ee.ui.layout.PercentageBasedHeight
import ee.ui.properties.Binding._
import scala.actors.Actor
import scala.actors.TIMEOUT
import ee.ui.events.MouseEvent
import ee.ui.display.Window
import ee.ui.display.Scene
import ee.ui.display.shape.Rectangle
import ee.ui.display.traits.ExplicitSize
import ee.ui.display.traits.ExtendedMouseTraits
import ee.ui.display.Node
import ee.ui.display.traits.ExplicitPosition
import ee.ui.display.Text
import ee.ui.display.Group
import ee.ui.display.traits.ExplicitWidth
import ee.ui.display.implementation.WindowImplementationHandler
import scala.language.implicitConversions
import ee.ui.system.RestrictedAccess

abstract class TestJavaFxApplication extends Application with Toolkit {
  
  implicit def colorToColorOption(c: Color): Option[Color] = Some(c)
  
  def start(stage: Window) = {
    println("start called")

    stage.title = "haha"

    stage.scene = new Scene {
      trait MouseListener extends ExtendedMouseTraits { self: Node =>
        val name: String

        onRollOver { e =>
          println(s"roll over $name")
        }
        onRollOut { e =>
          println(s"roll out $name")
        }
        onMouseOver { e =>
          println(s"mouse over $name")
        }
        onMouseOut { e =>
          println(s"mouse out $name")
        }
        onMouseDragOver { e =>
          println(s"mouse drag over $name")
        }
        onMouseDragOut { e =>
          println(s"mouse drag out $name")
        }
      }

      val rect1 = new Rectangle with ExplicitSize with MouseListener {
        val name = "rect1"
        //x = 10
        // y = 0
        width = 50
        height = 20
        fill = Color(0x00FF00, 0.5)

        fill <== hover map (if (_) Color(0xFFF0F0) else Color(0x00F0FF))
        /*
           * case true => Some(Color(0x00FFF0))
          case false => Some(Color(0x00FF0F))
           */
        /*
        fill <== onMouseOver map (e => Some(Color(0x00F0F0)))
        fill <== onMouseOut map (e => Some(Color(0x0FFF0F)))
        */
      }
      val boundsRect1 = new Rectangle with ExplicitPosition with ExplicitSize with MouseListener {
        val name = "boundsRect1"
        fill = None
        stroke = Color(0xFF0000, 0.8)
        strokeWidth = 1
      }
      val text1 = new Text with MouseListener {
        val name = "text1"
        text = "test"
        // y = 0
        //  textOrigin = VerticalPosition.TOP
      }
      val rect2 = new Rectangle with ExplicitSize with MouseListener {
        val name = "rect2"
        //x = 10
        // y = 0
        width = 50
        height = 20
        fill = Color(0x00FF00, 0.5)
        rotation <== rect1.rotation
      }
      val boundsRect2 = new Rectangle with ExplicitPosition with ExplicitSize with MouseListener {
        val name = "boundsRect2"
        fill = None
        stroke = Color(0xFF0000, 0.8)
        strokeWidth = 1
      }
      val text2 = new Text with MouseListener {
        val name = "text2"
        text = "test\ntest"
        // y = 0
        //  textOrigin = VerticalPosition.TOP
      }

      fill = Color(0xFF, 0.2)

      rect1.onMouseClicked {
        rect1.rotation = 20 + rect1.rotation
        //text.x = 10 + text.x
        toolkit.requestNextPulse
      }

      root = new Group with ExplicitPosition with MouseListener {
        val name = "root"
        x = 10
        y = 20

        children(
          boundsRect1,
          boundsRect2,

          new Group with HorizontalLayout with MouseListener {
            val name = "group1"

            children(
              rect1,
              text1,
              rect2,
              text2,
              new Rectangle with ExplicitWidth with PercentageBasedHeight with MouseListener {
                val name = "self resising rect"
                width = 100
                percentHeight = 100
                focused forNewValue { f => println(s"focus of $name: $f")}

                fill <== focused map (if (_) Color(0xFF0000) else Color(0x0000FF, 0.5))
              })

          },

          new Rectangle with ExplicitSize {
            width = 5
            height = 5
          },
        new Rectangle with ExplicitSize {
            width = 10
            height = 10
            fill = Color(0xFF0000, 0.5)
            
            onRollOver { e =>
              println("hoi")
              }
            }
          
         
        )

      }

      //TODO how to solve this with binding?
      rect1.bounds forNewValue { b =>
        boundsRect1.x = b.x
        boundsRect1.y = b.y
        boundsRect1.width = b.width
        boundsRect1.height = b.height
      }

      rect2.bounds forNewValue { b =>
        boundsRect2.x = b.x
        boundsRect2.y = b.y
        boundsRect2.width = b.width
        boundsRect2.height = b.height
      }
    }

    val timer = new Actor {
      def act {
        loop {
          reactWithin(100) {
            case TIMEOUT => toolkit.requestNextPulse
          }
        }
      }
    }
    timer.start

    show(stage)
  }
}

object TestJavaFxApplication extends JavaFxApplicationLauncher {
  def createApplication = new TestJavaFxApplication {
    val windowImplementationHandler = implicitly[WindowImplementationHandler]
  }
}